package com.mr.shiro.commons.shiro;

import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.LinkedHashMap;

/**
 * Class: ShiroConfiguration
 * User (作者):MRui
 * TODO (描述)：shiro核心配置文件类
 * Date 2019-01-13 22:57
 */
@Configuration//配置文件
public class ShiroConfiguration {

    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置自己的securityManager
        bean.setSecurityManager(securityManager);
        //设置登陆的url
        bean.setLoginUrl("/login");
        //登陆成功之后跳转的url
        bean.setSuccessUrl("/index");
        //设置没有权限访问的时候跳转url
        bean.setUnauthorizedUrl("/unauthorized");
        //核心某些请求该如何拦截key：请求（url） val：拦截器（DefaultFilter中的拦截器）
        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/index", "authc");//必须登陆authc：
        filterChainDefinitionMap.put("/login", "anon");//无需校验放行
        filterChainDefinitionMap.put("/**", "user");//登陆之后就可以访问
        filterChainDefinitionMap.put("/admin", "role[admin]");//不同角色访问不同的url（只有admin的角色才能访问admin）
        filterChainDefinitionMap.put("/edit", "perms[edit]");//不同权限访问不同的url（只有edit的权限才能访问edit）
        filterChainDefinitionMap.put("/druid/**", "anon");// 数据库访问监控 /druid/login.html 查看监控
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }
    /**
    * User (作者): MRui
    * TODO (描述)：securityManager
    * Data：2019-01-13 23:09
    */
    @Bean("securityManager")
    public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm){
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(authRealm);
        return manager;
    }

    /**
    * User (作者): MRui
    * TODO (描述)：授权认证  @Qualifier():使用spring上下文的内容
    * Data：2019-01-13 23:03
    */
    @Bean("authRealm")
    public AuthRealm authRealm(@Qualifier("credentialsMatcher") CustomCredentialsMatcher matcher){
        AuthRealm authRealm = new AuthRealm();
        authRealm.setCredentialsMatcher(matcher);//自己的密码比较器
        authRealm.setCacheManager(new MemoryConstrainedCacheManager());//授权认证缓存到内存中
        return authRealm;
    }

    /**
    * User (作者): MRui
    * TODO (描述)：密码自定义规则
    * Data：2019-01-13 23:02
    */
    @Bean("credentialsMatcher")
    public CustomCredentialsMatcher credentialsMatcher () {
        return new CustomCredentialsMatcher();
    }

    /**
    * User (作者): MRui
    * TODO (描述)：shiro与spring之间关联类
    * Data：2019-01-13 23:24
    */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        //将自己的manager传入
        advisor.setSecurityManager(securityManager);
        return advisor;
    }

    /**
    * User (作者): MRui
    * TODO (描述)：使用代理默认为false
    * Data：2019-01-13 23:29
    */
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }
}
